package com.cyt.reward.service.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.cyt.base.model.dto.ReturnResult;
import com.cyt.base.util.BaseConstant;
import com.cyt.base.util.BaseUtil;
import com.cyt.base.util.ErrorCode;
import com.cyt.reward.dao.RewardRecordDao;
import com.cyt.reward.dao.RewardStaffDao;
import com.cyt.reward.model.po.RewardRecord;
import com.cyt.reward.model.po.RewardStaff;
import com.cyt.reward.model.vo.RewardRecordVo;
import com.cyt.reward.service.RewardRecordService;
import com.cyt.reward.util.RewardDictCode;
import com.cyt.sys.model.po.SysUser;
import com.cyt.sys.service.impl.BaseServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 打赏功能-打赏记录Service层实现类
 *
 * @author rong yuan
 * @date 2019-7-24 13:44:53
 */
@Service("rewardRecordService")
public class RewardRecordServiceImpl extends BaseServiceImpl<RewardRecord> implements RewardRecordService {

    @Resource
    private RewardRecordDao rewardRecordDao;
    @Resource
    private RewardStaffDao rewardStaffDao;

    @Autowired
    public void setBaseDao(RewardRecordDao rewardRecordDao) {
        this.baseDao = rewardRecordDao;
    }

    /**
     * 分页查询
     *
     * @param rewardRecordVo 接受参数对象
     * @param pageNum        分页数
     * @param pageSize       每页显示条数
     * @return ReturnResult
     * @author rong yuan
     * @date 2019-7-24 13:44:53
     */
    @Override
    public ReturnResult page(RewardRecordVo rewardRecordVo, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        PageHelper.orderBy(" create_time desc");
        List<RewardRecordVo> list = rewardRecordDao.selectByCondition(rewardRecordVo);
        PageInfo<RewardRecordVo> page = new PageInfo<>(list);
        if (page.getList() != null && page.getList().size() > 0) {
            for (RewardRecordVo vo : page.getList()) {
                vo.setNickName(BaseUtil.decodeBase64(vo.getNickName()));
            }
        }
        return new ReturnResult(page.getList(), page.getTotal(), page.isHasNextPage());
    }

    /**
     * 添加或更新
     *
     * @param rewardRecordVo 参数接受对象
     * @param sysUser        当前用户
     * @return ReturnResult
     * @author rong yuan
     * @date 2019-7-24 13:44:53
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ReturnResult addOrUpdate(RewardRecordVo rewardRecordVo, SysUser sysUser) {
        if (StrUtil.isEmpty(rewardRecordVo.getId())) {
            RewardRecord rewardRecord = new RewardRecord(sysUser);
            rewardRecord.setApplyId(rewardRecordVo.getApplyId());
            rewardRecord.setStaffId(rewardRecordVo.getStaffId());
            rewardRecord.setMoney(Double.parseDouble(rewardRecordVo.getMoney()));
            rewardRecord.setStars(rewardRecordVo.getStars());
            rewardRecord.setTagName(rewardRecordVo.getTagName());
            rewardRecord.setComments(rewardRecordVo.getComments());
            rewardRecord.setMemberId(rewardRecordVo.getMemberId());
            rewardRecord.setPayStatus(rewardRecordVo.getPayStatus());
            int num = rewardRecordDao.insert(rewardRecord);
            if (num > 0) {
                if (RewardDictCode.REWARD_PAY_STATUS_YZF.equals(rewardRecordVo.getPayStatus())) {
                    updateRewardStaff(rewardRecordVo.getApplyId(), rewardRecordVo.getStaffId(), rewardRecord.getMoney());
                }
                return new ReturnResult(rewardRecord);
            } else {
                return new ReturnResult(ErrorCode.CODE_1, BaseConstant.DATABASE_ERROR_INSERT);
            }
        } else {
            RewardRecord rewardRecord = rewardRecordDao.selectByPrimaryKey(rewardRecordVo.getId());
            rewardRecord.setApplyId(rewardRecordVo.getApplyId());
            rewardRecord.setStaffId(rewardRecordVo.getStaffId());
            rewardRecord.setMoney(Double.parseDouble(rewardRecordVo.getMoney()));
            rewardRecord.setStars(rewardRecordVo.getStars());
            rewardRecord.setTagName(rewardRecordVo.getTagName());
            rewardRecord.setComments(rewardRecordVo.getComments());
            rewardRecord.setMemberId(rewardRecordVo.getMemberId());
            rewardRecord.setUpdateTime(new Date());
            rewardRecord.setUpdateUser(sysUser.getId());
            int num = rewardRecordDao.updateByPrimaryKey(rewardRecord);
            if (num > 0) {
                return new ReturnResult(rewardRecord);
            } else {
                return new ReturnResult(ErrorCode.CODE_1, BaseConstant.DATABASE_ERROR_UPDATE);
            }
        }
    }

    private void updateRewardStaff(String applyId, String staffId, double money) {
        Example example;
        Example.Criteria criteria;
        //已评价次数
        example = new Example(RewardRecord.class);
        criteria = example.createCriteria();
        criteria.andEqualTo("applyId", applyId);
        criteria.andEqualTo("staffId", staffId);
        criteria.andEqualTo("removeTag", BaseConstant.REMOVE_TAG_NO);
        List<RewardRecord> rewardRecordList = rewardRecordDao.selectByExample(example);

        int num = 0;
        int stars = 0;
        if (rewardRecordList != null && rewardRecordList.size() > 0) {
            num = rewardRecordList.size();
            for (RewardRecord rewardRecord : rewardRecordList) {
                stars += Integer.parseInt(rewardRecord.getStars());
            }
        }
        //更新员工信息
        example = new Example(RewardStaff.class);
        criteria = example.createCriteria();
        criteria.andEqualTo("id", staffId);
        criteria.andEqualTo("applyId", applyId);
        criteria.andEqualTo("removeTag", BaseConstant.REMOVE_TAG_NO);
        List<RewardStaff> rewardStaffList = rewardStaffDao.selectByExample(example);
        if (rewardStaffList != null && rewardStaffList.size() == 1) {
            RewardStaff rewardStaff = rewardStaffList.get(0);
            rewardStaff.setTotalMoney(rewardStaff.getTotalMoney() + money);
            rewardStaff.setHaveMoney(rewardStaff.getHaveMoney() + money);
            if (num != 0) {
                String averageStars = String.valueOf((double) stars / num);
                String integer = averageStars.substring(0, averageStars.indexOf("."));
                String decimal = averageStars.substring(averageStars.indexOf(".") + 1, averageStars.indexOf(".") + 2);
                if (Integer.parseInt(String.valueOf(decimal.charAt(0))) < 5) {
                    rewardStaff.setStars(Double.parseDouble(integer + ".0"));
                } else {
                    rewardStaff.setStars(Double.parseDouble(integer + ".5"));
                }
            }
            rewardStaffDao.updateByPrimaryKey(rewardStaff);
        }
    }

    /**
     * 昨日赏金统计
     *
     * @param rewardRecordVo 参数接受对象
     * @return double
     * @author rong yuan
     * @date 2019/7/26 08:13
     */
    @Override
    public double statisticsMoney(RewardRecordVo rewardRecordVo) {
        return rewardRecordDao.statisticsMoney(rewardRecordVo);
    }

    /**
     * 支付成功修改状态
     *
     * @param id       支付记录ID
     * @param wechatNo 订单号
     * @author rong yuan
     * @date 2019/7/26 13:56
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateAfterPay(String id, String wechatNo) {
        RewardRecord rewardRecord = rewardRecordDao.selectByPrimaryKey(id);
        rewardRecord.setPayStatus(RewardDictCode.REWARD_PAY_STATUS_YZF);
        rewardRecordDao.updateByPrimaryKey(rewardRecord);
        updateRewardStaff(rewardRecord.getApplyId(), rewardRecord.getStaffId(), rewardRecord.getMoney());
    }

    /**
     * 首页统计
     *
     * @param rewardRecordVo 参数接受对象
     * @return List<Object>
     * @author rong yuan
     * @date 2019-8-19 11:24
     */
    @Override
    public List<Object> statistics(RewardRecordVo rewardRecordVo) {
        //头部统计
        rewardRecordVo.setStartTime(DateUtil.beginOfDay(DateUtil.yesterday().toJdkDate()).toString(DatePattern.NORM_DATETIME_PATTERN));
        rewardRecordVo.setEndTime(DateUtil.endOfDay(DateUtil.yesterday().toJdkDate()).toString(DatePattern.NORM_DATETIME_PATTERN));
        int staffNumYesterday = rewardRecordDao.statisticsStaffNum(rewardRecordVo);
        double starFiveYesterday = rewardRecordDao.statisticsStarFive(rewardRecordVo);
        double moneyYesterday = rewardRecordDao.statisticsMoney(rewardRecordVo);
        rewardRecordVo.setStartTime(null);
        rewardRecordVo.setEndTime(null);
        double moneyAll = rewardRecordDao.statisticsMoney(rewardRecordVo);
        //每日统计
        List<String> dayList = new ArrayList<>();
        for (int i = 0; i < 7; i++) {
            dayList.add(DateUtil.formatDate(DateUtil.offsetDay(new Date(), (i - 6))));
        }
        rewardRecordVo.setStartTime(DateUtil.beginOfDay(DateUtil.offsetDay(new Date(), -6)).toString(DatePattern.NORM_DATETIME_PATTERN));
        rewardRecordVo.setEndTime(DateUtil.endOfDay(new Date()).toString(DatePattern.NORM_DATETIME_PATTERN));
        List<Map> staffNumEveryDay = rewardRecordDao.statisticsStaffNumEveryDay(rewardRecordVo);
        List<Integer> staffNumList = getStaffNumEveryDay(dayList, staffNumEveryDay);
        List<Map> moneyEveryDay = rewardRecordDao.statisticsMoneyEveryDay(rewardRecordVo);
        List<Double> money = getMoneyEveryDay(dayList, moneyEveryDay);
        //员工佣金
        rewardRecordVo.setStartTime(DateUtil.beginOfMonth(new Date()).toString(DatePattern.NORM_DATETIME_PATTERN));
        rewardRecordVo.setEndTime(DateUtil.endOfMonth(new Date()).toString(DatePattern.NORM_DATETIME_PATTERN));
        List<Map> staffMoneyEveryMonth = rewardRecordDao.statisticsStaffMoney(rewardRecordVo);
        List<String> staffListEveryMonth = new ArrayList<>();
        List<Double> moneyListEveryMonth = new ArrayList<>();
        if (staffMoneyEveryMonth != null) {
            for (Map map : staffMoneyEveryMonth) {
                staffListEveryMonth.add(map.get("name").toString());
                moneyListEveryMonth.add((Double) map.get("money"));
            }
        }
        rewardRecordVo.setStartTime(null);
        rewardRecordVo.setEndTime(null);
        List<Map> staffMoney = rewardRecordDao.statisticsStaffMoney(rewardRecordVo);
        List<String> staffList = new ArrayList<>();
        List<Double> moneyList = new ArrayList<>();
        if (staffMoney != null) {
            for (Map map : staffMoney) {
                staffList.add(map.get("name").toString());
                moneyList.add((Double) map.get("money"));
            }
        }

        List<Object> result = new ArrayList<>();
        result.add(staffNumYesterday);
        result.add(starFiveYesterday);
        result.add(moneyYesterday);
        result.add(moneyAll);
        result.add(dayList);
        result.add(staffNumList);
        result.add(money);
        result.add(staffListEveryMonth);
        result.add(moneyListEveryMonth);
        result.add(staffList);
        result.add(moneyList);
        return result;
    }

    private List<Double> getMoneyEveryDay(List<String> dayList, List<Map> moneyEveryDay) {
        List<Double> moneyList = new ArrayList<>();
        for (String day : dayList) {
            if (CollectionUtils.isNotEmpty(moneyEveryDay)) {
                for (int i = 0; i < moneyEveryDay.size(); i++) {
                    Map map = moneyEveryDay.get(i);
                    if (map.get("createTime").toString().equals(day)) {
                        moneyList.add((Double) map.get("money"));
                        break;
                    } else {
                        if (i == moneyEveryDay.size() - 1) {
                            moneyList.add(0d);
                        }
                    }
                }
            } else {
                moneyList.add(0d);
            }
        }
        return moneyList;
    }

    private List<Integer> getStaffNumEveryDay(List<String> dayList, List<Map> staffNumEveryDay) {
        List<Integer> staffNumList = new ArrayList<>();
        for (String day : dayList) {
            if (CollectionUtils.isNotEmpty(staffNumEveryDay)) {
                for (int i = 0; i < staffNumEveryDay.size(); i++) {
                    Map map = staffNumEveryDay.get(i);
                    if (map.get("createTime").toString().equals(day)) {
                        staffNumList.add(((Long) map.get("staffNum")).intValue());
                        break;
                    } else {
                        if (i == staffNumEveryDay.size() - 1) {
                            staffNumList.add(0);
                        }
                    }
                }
            } else {
                staffNumList.add(0);
            }
        }
        return staffNumList;
    }
}